﻿using System;
using System.Collections.Generic;
using System.Linq;
using AutoMapper;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using Shop.Base.Entity;
using Shop.Base.Entity.Assist;
using Shop.Base.Entity.Delete;
using Shop.Base.Entity.Insert;
using Shop.Base.Entity.Select;
using Shop.Base.Entity.Update;
using Shop.Base.Interface;
using Shop.Entity;
using Shop.Tools;
using Shop.Web.Models;

namespace Shop.Web.Areas.Admin.Controllers
{
    [Area("Admin")]
    public class SystemRoleController : Controller
    {
        private IMapper mapper;
        private ISystemMenu menu;
        private ISystemMenuButton menuButton;
        private ISystemButton button;
        private ISystemRole role;
        private ISystemRoleFunction roleFunction;

        public SystemRoleController(IMapper _mapper, ISystemMenu _menu, ISystemMenuButton _menuButton, ISystemButton _button, ISystemRole _role, ISystemRoleFunction _roleFunction)
        {
            this.mapper = _mapper;
            this.menu = _menu;
            this.menuButton = _menuButton;
            this.button = _button;
            this.role = _role;
            this.roleFunction = _roleFunction;
        }
        // GET
        public IActionResult Index()
        {
            return View();
        }

        [HttpGet]
        public IActionResult GetList(string name, int isDel = -1, int pageIndex = 1, int pageSize = 15)
        {
            try
            {
                var list = role.GetPage(name, isDel, pageIndex, pageSize, out int total);
                var showList = mapper.Map<List<SystemRolePo>, List<ShowSystemRole>>(list);
                if (showList.Any())
                {
                    ////Users
                    //var all = role.GetAll();
                    //showList.ForEach(x =>
                    //{
                    //    if (all.Any(c => c.Id == x.ParentId))
                    //    {
                    //        x.Users = "暂无用户";
                    //    }
                    //});
                }
                return Json(new ResultModel
                {
                    code = OperationResultType.GetList,
                    data = new { list = showList, total },
                    error_msg = "",
                    success = true
                });
            }
            catch (Exception e)
            {
                Tools.StaticConst.log.Error(e);
                return Json(new ResultModel { code = OperationResultType.Throws, data = new List<string>(), error_msg = "查询异常", success = false });
            }
        }

        public IActionResult Edit(Guid? roleId)
        {
            var comUser = HttpContext.Session.Get<ComUser>(SessionKeys.UserInfo);
            if (roleId.HasValue && !roleId.Value.IsEmptyGuid())
            {
                var roles = role.Find<SystemRolePo>(roleId.Value);
                roles.UpdateId = comUser.Id;
                roles.UpdateName = comUser.UserName;
                roles.UpdateAt = DateTime.Now;
                ViewBag.model = roles.ToJsonData();
            }
            else
            {
                ViewBag.model = new AddSystemRole { CreateId = comUser.Id, CreateName = comUser.UserName }.ToJsonData();
            }
            return View();
        }

        [HttpPost]
        [ValidateAntiForgeryToken]
        public IActionResult Edit([FromForm]SystemRolePo model)
        {
            try
            {
                if (ModelState.IsValid)
                {
                    var comUser = HttpContext.Session.Get<ComUser>(SessionKeys.UserInfo);
                    if (model.Id.IsEmptyGuid())
                    {
                        var inserts = mapper.Map<SystemRolePo, AddSystemRole>(model);
                        role.Insert(inserts, comUser);
                    }
                    else
                    {
                        var updates = mapper.Map<SystemRolePo, UpdateSystemRole>(model);
                        role.Update(updates, comUser);
                    }
                    return RedirectToAction("Index");
                }
                ViewBag.model = model.ToJsonData();
                TempData["errMsg"] = new JsMessage("无效的操作", 5, JsMessageType.Warning).ToString();
                return View();
            }
            catch (Exception e)
            {
                Tools.StaticConst.log.Error(e);
                ViewBag.model = model.ToJsonData();
                if (e.Message.Contains("#"))
                    TempData["errMsg"] = new JsMessage(e.Message.Replace("#", ""), 5, JsMessageType.Warning).ToString();
                else
                    TempData["errMsg"] = new JsMessage("保存出现异常", 5, JsMessageType.Danger).ToString();
                return View();
            }
        }

        [HttpPost]
        public IActionResult Delete(Guid id)
        {
            try
            {
                if (id.IsEmptyGuid()) return Json(new ResultModel { code = OperationResultType.ParamError, error_msg = "指定删除的角色不存在", success = false });
                var comUser = HttpContext.Session.Get<ComUser>(SessionKeys.UserInfo);
                role.Delete<UpdateSystemRole>(id, comUser);
                return Json(new ResultModel { code = OperationResultType.Success, error_msg = "删除成功", success = true });
            }
            catch (Exception e)
            {
                Tools.StaticConst.log.Error(e);
                return Json(new ResultModel { code = OperationResultType.Throws, error_msg = "系统异常，请刷新再试", success = false });
            }
        }

        //设置角色菜单
        public IActionResult SetFunction(Guid roleId)
        {
            if (roleId.IsEmptyGuid()) return RedirectToAction("Index");
            ViewBag.Data = RoleMenus();
            ViewBag.roleId = roleId;
            ViewBag.selectedMenu = "[]";
            var hasSave = roleFunction.GetAll(roleId);
            if (hasSave.Any(x=>x.IsDel==false))
            {
                var allMenu = menu.GetAll().Where(x => x.IsDel == false);
                var myList=new List<string>();
                var noDel = hasSave.Where(x => x.IsDel == false).ToList();
                noDel.ForEach(x =>
                {
                    if (x.ButtonId != Guid.Empty&&!myList.Contains($"{x.ButtonId}"))
                    {
                        myList.Add($"{x.ButtonId}");
                    }
                    else
                    {
                        if (!noDel.Any(c => c.MenuId == x.MenuId && c.Id != x.Id)&&!allMenu.Any(c=>c.ParentId==x.MenuId)&& !myList.Contains($"{x.MenuId}"))
                        {
                            myList.Add($"{x.MenuId}");
                        }
                    }
                });
                ViewBag.selectedMenu = myList.ToJsonData();
            }
            return View();
        }

        [HttpPost]
        [ValidateAntiForgeryToken]
        public IActionResult SetFunction(List<string> list,Guid roleId)
        {
            if (roleId.IsEmptyGuid()) return RedirectToAction("Index");
            //所有菜单及按钮
            ViewBag.Data = RoleMenus();
            //角色Id
            ViewBag.roleId = roleId;
            //已选中 菜单及按钮
            var selectMenu=list.Select(x=>x.Split('=')[1]);
            ViewBag.selectedMenu = selectMenu.ToJsonData();
            try
            {
                var comUser = HttpContext.Session.Get<ComUser>(SessionKeys.UserInfo);
                roleFunction.MultSave(list, roleId, comUser);
                return RedirectToAction("Index");
            }
            catch (Exception e)
            {
                Tools.StaticConst.log.Error(e);
                if (e.Message.Contains("#"))
                    TempData["errMsg"] = new JsMessage(e.Message.Replace("#", ""), 5, JsMessageType.Warning).ToString();
                else
                    TempData["errMsg"] = new JsMessage("保存出现异常", 5, JsMessageType.Danger).ToString();
            }
            return View();
        }

        private string RoleMenus()
        {
            //所有菜单
            var allMenu = menu.GetAll().Where(x => x.IsDel == false).ToList();
            //所有菜单按钮
            var allButon = menuButton.GetAll();
            var sourceList = new List<SystemTreeHelp>();
            var targetList = new List<SystemTreeHelp>();
            if (allMenu.Any())
            {
                allMenu.ForEach(x =>
                {
                    var pid = "";
                    if (x.ParentId.HasValue && allMenu.Any(c => c.Id == x.ParentId&&c.ParentId.HasValue&&!c.ParentId.Value.IsEmptyGuid()))
                    {
                        var parents = allMenu.FirstOrDefault(c => c.Id == x.ParentId);
                        pid = parents!=null&&parents.ParentId.HasValue&&!parents.ParentId.Value.IsEmptyGuid()?parents.ParentId.Value + "*":"";
                    }
                    sourceList.Add(new SystemTreeHelp
                    {
                        ParentId = x.ParentId.HasValue ? x.ParentId.Value + "" : "",
                        FunctionId = x.Id + "",
                        FunctionName = x.MemuName,
                        FullParentId = pid + (x.ParentId.HasValue ? x.ParentId.Value + "" : "")
                    });
                    if (allButon.Any(c => c.MenuId == x.Id))
                    {
                        allButon.Where(d => d.MenuId == x.Id).OrderBy(c=>c.ButtonName).ToList().ForEach(y =>
                            {
                                sourceList.Add(new SystemTreeHelp
                                {
                                    ParentId = y.MenuId + "",
                                    FunctionId = y.Id + "",
                                    FunctionName = x.MemuName + "->" + y.ButtonName,
                                    Isbutton = true,
                                    FullParentId = pid+(x.ParentId.HasValue ? x.ParentId.Value + "" : "")+"*"+ x.Id + "|"+ y.Id
                                });
                            });
                    }
                });
                LoadTree(sourceList, targetList, "");
            }
            return targetList.ToJsonData();
        }

        private List<SystemTreeHelp> LoadTree(List<SystemTreeHelp> source, List<SystemTreeHelp> target, string parentId)
        {
            foreach (var item in source.Where(x => x.ParentId == parentId))
            {
                var childNode = source.Where(x => x.ParentId == item.FunctionId).ToList();
                if (childNode.Any())
                {
                    LoadTree(source, item.Childs, item.FunctionId);
                }
                target.Add(item);
            }
            return target;
        }
    }
}